package com.naiterui.ehp.bs.cms.modules.devops.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.utils.beans.BeanUtil;
import com.naiterui.ehp.bs.cms.common.constants.DsName;
import com.naiterui.ehp.bs.cms.common.entity.BaseEntity;
import com.naiterui.ehp.bs.cms.modules.devops.entity.AppVersion;
import com.naiterui.ehp.bs.cms.modules.devops.feign.DoctorFeign;
import com.naiterui.ehp.bs.cms.modules.devops.feign.PharmacistFeign;
import com.naiterui.ehp.bs.cms.modules.devops.mapper.AppVersionMapper;
import com.naiterui.ehp.bs.cms.modules.devops.service.VersionService;
import com.naiterui.ehp.bs.cms.modules.devops.vo.AppVersionVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author luao
 * @date 2022/4/1 7:01 PM
 **/
@DS(DsName.EHP)
@Service
@RequiredArgsConstructor
public class VersionServiceImpl implements VersionService {

    private final AppVersionMapper appVersionMapper;

    private final DoctorFeign doctorFeign;
    private final PharmacistFeign pharmacistFeign;

    @Value("${file.base.prefix}")
    private String fileBasePrefix;

    @Value("${ehp.android-apk-path}")
    private String androidApkPath;

    @Value("${ehp.domain.img}")
    private String imgHost;

    @Override
    public List<AppVersionVO> appVersionList(Integer status) {
        LambdaQueryWrapper<AppVersion> queryWrapper = new QueryWrapper<AppVersion>().lambda()
            .eq(status != null, AppVersion::getStatus, status).orderByDesc(BaseEntity::getChangedAt);
        List<AppVersion> appVersions = appVersionMapper.selectList(queryWrapper);
        List<AppVersionVO> appVersionVOS = new ArrayList<>();
        BeanUtil.copyList(appVersions, appVersionVOS, AppVersionVO.class);
        return appVersionVOS;
    }

    @Override
    public void addAppVersion(AppVersionVO appVersionVO) {
        AppVersion appVersion = new AppVersion();
        BeanUtil.copyProperties(appVersionVO, appVersion);
        appVersion.setStatus(AppVersion.STATUS_DISABLED);
        appVersionMapper.insert(appVersion);
    }

    @Override
    public void updateAppVersion(AppVersionVO appVersionVO) throws BusinessException {
        AppVersion appVersion = appVersionMapper.selectById(appVersionVO.getId());
        if (appVersion == null) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "版本不存在");
        }
        // 如果当前升级启用中，修改版本升级信息
        if (appVersion.getStatus() == AppVersion.STATUS_ENABLE) {
            // 设置升级
            if (appVersion.getAppType() == AppVersion.APP_TYPE_DOCTOR) {
                RedisUtil.keyOps().delete(CommonConstant.DR_VERSION_CHECK_KEY + appVersion.getAppPlat());
                RedisUtil.keyOps().delete(CommonConstant.DR_FORCE_VERSION_KEY + appVersion.getAppPlat());
                doctorFeign.saveVersion(appVersion.getAppPlat(), appVersion.getLastVerNum(),
                        appVersion.getLastVerSize(), appVersion.getResult(), appVersion.getForceVersion(),
                        appVersion.getContent(), appVersion.getUrl());
            } else {
                RedisUtil.keyOps().delete(CommonConstant.PH_VERSION_CHECK_KEY + appVersion.getAppPlat());
                RedisUtil.keyOps().delete(CommonConstant.PH_FORCE_VERSION_KEY + appVersion.getAppPlat());
                pharmacistFeign.saveVersion(appVersion.getAppPlat(), appVersion.getLastVerNum(),
                        appVersion.getLastVerSize(), appVersion.getResult(), appVersion.getForceVersion(),
                        appVersion.getContent(), appVersion.getUrl());
            }
        }
        BeanUtil.copyProperties(appVersionVO, appVersion);
        appVersionMapper.updateById(appVersion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void versionEnable(Long id) throws BusinessException {
        AppVersion appVersion = appVersionMapper.selectById(id);
        if (appVersion == null) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "版本不存在");
        }
        if (appVersion.getStatus() == AppVersion.STATUS_ENABLE) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "当前版本已启用");
        }
        // 将之前该平台下的版本禁用
        List<AppVersion> appVersions = appVersionMapper.selectList(new QueryWrapper<AppVersion>().lambda()
                .eq(AppVersion::getAppPlat, appVersion.getAppPlat()).eq(AppVersion::getStatus, AppVersion.STATUS_ENABLE)
                .eq(AppVersion::getAppType, appVersion.getAppType()));
        if (!CollectionUtils.isEmpty(appVersions)) {
            appVersions.stream().forEach(item -> {
                item.setStatus(AppVersion.STATUS_DISABLED);
                appVersionMapper.updateById(item);
            });
        }
        // 设置升级
        if (appVersion.getAppType() == AppVersion.APP_TYPE_DOCTOR) {
            doctorFeign.saveVersion(appVersion.getAppPlat(), appVersion.getLastVerNum(), appVersion.getLastVerSize(),
                    appVersion.getResult(), appVersion.getForceVersion(), appVersion.getContent(), appVersion.getUrl());
        } else {
            pharmacistFeign.saveVersion(appVersion.getAppPlat(), appVersion.getLastVerNum(),
                    appVersion.getLastVerSize(), appVersion.getResult(), appVersion.getForceVersion(),
                    appVersion.getContent(), appVersion.getUrl());
        }
        // 版本启用
        appVersion.setStatus(AppVersion.STATUS_ENABLE);
        appVersionMapper.updateById(appVersion);
    }

    @Override
    public void versionDisable(Long id) throws BusinessException {
        AppVersion appVersion = appVersionMapper.selectById(id);
        if (appVersion == null) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "版本不存在");
        }
        if (appVersion.getStatus() == AppVersion.STATUS_DISABLED) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "当前版本已禁用");
        }
        if (appVersion.getAppType() == AppVersion.APP_TYPE_DOCTOR) {
            RedisUtil.keyOps().delete(CommonConstant.DR_VERSION_CHECK_KEY + appVersion.getAppPlat());
            RedisUtil.keyOps().delete(CommonConstant.DR_FORCE_VERSION_KEY + appVersion.getAppPlat());
        } else {
            RedisUtil.keyOps().delete(CommonConstant.PH_VERSION_CHECK_KEY + appVersion.getAppPlat());
            RedisUtil.keyOps().delete(CommonConstant.PH_FORCE_VERSION_KEY + appVersion.getAppPlat());
        }
        appVersion.setStatus(AppVersion.STATUS_DISABLED);
        appVersionMapper.updateById(appVersion);
    }

    @Override
    public String uploadApk(MultipartFile file) throws BusinessException, IOException {
        String fileName = UUID.randomUUID() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        String filePath = fileBasePrefix + androidApkPath + fileName;
        File newFile = new File(filePath);
        if (!newFile.exists()) {
            FileUtils.forceMkdirParent(newFile);
        }
        FileUtils.copyInputStreamToFile(file.getInputStream(), newFile);
        return imgHost + androidApkPath + fileName;
    }
}
